package service

import (
	"context"
	"errors"
	nwv1 "k8s.io/api/networking/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"log"
)

type ingress struct {}

var Ingress ingress

//创建ingress需要的参数结构体
type IngressCreate struct {
	Name string `json:"name"`
	Namespace string `json:"namespace"`
	Label map[string]string `json:"label"`
	Hosts map[string][]*HttpPath `json:"hosts"`
}

//定义ingress的path结构体
type HttpPath struct {
	Path string `json:"path"`
	PathType nwv1.PathType `json:"path_type"`
	ServiceName string `json:"service_name"`
	ServicePort int32 `json:"service_port"`
}

//创建ingress
func (i *ingress)CreateIngress(data *IngressCreate) (err error) {
	//声明nwv1.IngressRule和HTTPIngressPath变量 后面组装数据用到
	var ingressRules []nwv1.IngressRule
	var httpIngressPaths []nwv1.HTTPIngressPath
	//将data中的数据组成nwv1.Ingress对象
	ingress := &nwv1.Ingress{
		TypeMeta:   metav1.TypeMeta{},
		ObjectMeta: metav1.ObjectMeta{
			Name: data.Name,
			Namespace: data.Namespace,
			Labels: data.Label,
		},
		Spec:       nwv1.IngressSpec{},
		Status:     nwv1.IngressStatus{},
	}
	//第一层for循环将host组装成nwv1.IngressRule对象
	//一个host对应一个ingressRules 一个ingressRules包含一个host和多个path
	for key ,value := range data.Hosts {
		ir := nwv1.IngressRule{
			Host:             key,
			//这里将IngressRuleValue的Paths置空 后面组装好数据在赋值
			IngressRuleValue: nwv1.IngressRuleValue{
				HTTP: &nwv1.HTTPIngressRuleValue{Paths: nil},
			},
		}
		//第二层for将path组装成nwv1.HTTPIngressPath类型的对象
		for _,httpPath := range value{
			hip := nwv1.HTTPIngressPath{
				Path:     httpPath.Path,
				PathType: &httpPath.PathType,
				Backend:  nwv1.IngressBackend{
					Service: &nwv1.IngressServiceBackend{
						Name: httpPath.ServiceName,
						Port: nwv1.ServiceBackendPort{
							Number: httpPath.ServicePort,
						},
					},
				},
			}
			//将每个hip对象组成数组
			httpIngressPaths = append(httpIngressPaths,hip)
		}
		//给前面置空的paths赋值
		ir.IngressRuleValue.HTTP.Paths = httpIngressPaths
		//将每个ir对象组装成数组 这个ir对象就是IngressRule 每个元素是一个host和多个path
		ingressRules = append(ingressRules,ir)
	}
	//将ingressRules对象加入到ingress规则当中
	ingress.Spec.Rules = ingressRules
	//创建ingress
	_ ,err = K8s.ClientSet.NetworkingV1().Ingresses(data.Namespace).Create(context.TODO(),ingress,metav1.CreateOptions{})
	if err != nil {
		log.Printf("创建ingress失败：%s", err)
		return errors.New("创建ingress失败：%s" + err.Error())
	}
	return nil
}

/*
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-wildcard-host
spec:
  rules:
  - host: "foo.bar.com"
    http:
      paths:
      - pathType: Prefix
        path: "/bar"
        backend:
          service:
            name: service1
            port:
              number: 80
  - host: "*.foo.com"
    http:
      paths:
      - pathType: Prefix
        path: "/foo"
        backend:
          service:
            name: service2
            port:
              number: 80
*/


//删除ingress
func (i *ingress)DeleteIngress(ingrssname,namespace string) (err error) {
	err = K8s.ClientSet.NetworkingV1().Ingresses(namespace).Delete(context.TODO(),ingrssname,metav1.DeleteOptions{})
	if err != nil {
		log.Printf("删除ingress失败：%s", err)
		return errors.New("删除ingress失败：%s" + err.Error())
	}
	return nil
}











